/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dal_cyclonedds/converter/StatusConverter.hpp"
#include "dal_cyclonedds/converter/InstanceHandleConverter.hpp"

StatusConverter* StatusConverter::singleton_ = nullptr;

StatusConverter::StatusConverter() {}

StatusConverter* StatusConverter::GetInstance()
{
    if (singleton_ == nullptr) {
        singleton_ = new StatusConverter();
    }
    return singleton_;
}

dal_ret_t StatusConverter::ConvertInconsistentTopicStatusFromCycloneddsToDal(
    const dds_inconsistent_topic_status_t* c_status, dal_inconsistent_topic_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    return DAL_RETCODE_OK;
}

dal_ret_t
StatusConverter::ConvertSampleLostStatusFromCycloneddsToDal(const dds_sample_lost_status_t* c_status,
                                                         dal_sample_lost_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    return DAL_RETCODE_OK;
}

dal_ret_t
StatusConverter::ConvertSampleRejectedStatusFromCycloneddsToDal(const dds_sample_rejected_status_t* c_status,
                                                             dal_sample_rejected_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    switch (c_status->last_reason) {
        default:
        case DDS_NOT_REJECTED:
            d_status->last_reason = DAL_NOT_REJECTED;
            break;
        case DDS_REJECTED_BY_INSTANCES_LIMIT:
            d_status->last_reason =
                static_cast<dal_sample_rejected_status_kind_t>(DAL_REJECTED_BY_INSTANCES_LIMIT);
            break;
        case DDS_REJECTED_BY_SAMPLES_LIMIT:
            d_status->last_reason =
                static_cast<dal_sample_rejected_status_kind_t>(DAL_REJECTED_BY_SAMPLES_LIMIT);
            break;
        case DDS_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT:
            d_status->last_reason = static_cast<dal_sample_rejected_status_kind_t>(
                DAL_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT);
            break;
    }
    InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromCycloneddsToDal(
        &c_status->last_instance_handle, &d_status->last_instance_handle);
    return DAL_RETCODE_OK;
}

dal_ret_t
StatusConverter::ConvertLivelinessLostStatusFromCycloneddsToDal(const dds_liveliness_lost_status_t* c_status,
                                                             dal_liveliness_lost_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertLivelinessChangedStatusFromCycloneddsToDal(
    const dds_liveliness_changed_status_t* c_status, dal_liveliness_changed_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->alive_count = c_status->alive_count;
    d_status->not_alive_count = c_status->not_alive_count;
    d_status->alive_count_change = c_status->alive_count_change;
    d_status->not_alive_count_change = c_status->not_alive_count_change;

    InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromCycloneddsToDal(
        &c_status->last_publication_handle, &d_status->last_publication_handle);
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertOfferedDeadlineMissedStatusFromCycloneddsToDal(
    const dds_offered_deadline_missed_status_t* c_status, dal_offered_deadline_missed_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;

    InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromCycloneddsToDal(
        &c_status->last_instance_handle, &d_status->last_instance_handle);
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertRequestedDeadlineMissedStatusFromCycloneddsToDal(
    const dds_requested_deadline_missed_status_t* c_status, dal_requested_deadline_missed_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;

    InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromCycloneddsToDal(
        &c_status->last_instance_handle, &d_status->last_instance_handle);
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertOfferedIncompatibleQosStatusFromCycloneddsToDal(
    const dds_offered_incompatible_qos_status_t* c_status, dal_offered_incompatible_qos_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    d_status->last_policy_id = static_cast<dal_qos_policy_e>(c_status->last_policy_id);
    // TODO: QosPolicyCountSeq
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertRequestedIncompatibleQosStatusFromCycloneddsToDal(
    const dds_requested_incompatible_qos_status_t* c_status, dal_requested_incompatible_qos_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    d_status->last_policy_id = static_cast<dal_qos_policy_e>(c_status->last_policy_id);
    // TODO: QosPolicyCountSeq
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertPublicationMatchedStatusFromCycloneddsToDal(
    const dds_publication_matched_status_t* c_status, dal_publication_matched_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    d_status->current_count = c_status->current_count;
    d_status->current_count_change = c_status->current_count_change;

    InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromCycloneddsToDal(
        &c_status->last_subscription_handle, &d_status->last_subscription_handle);
    
    return DAL_RETCODE_OK;
}

dal_ret_t StatusConverter::ConvertSubscriptionMatchedStatusFromCycloneddsToDal(
    const dds_subscription_matched_status_t* c_status, dal_subscription_matched_status_t* d_status)
{
    if (c_status == nullptr || d_status == nullptr) {
        return DAL_RETCODE_BAD_PARAMETER;
    }

    d_status->total_count = c_status->total_count;
    d_status->total_count_change = c_status->total_count_change;
    d_status->current_count = c_status->current_count;
    d_status->current_count_change = c_status->current_count_change;

    InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromCycloneddsToDal(
        &c_status->last_publication_handle, &d_status->last_publication_handle);

    return DAL_RETCODE_OK;
}
